﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataTransferObject.DiaryAndTrackingTask.SupportClassForDiary;
using System.Data;


namespace DataTransferObject.DiaryAndTrackingTask
{
    namespace SupportClassForDiary
    {
        [Serializable]
        public enum EventPriority { A = 0, B = 1, C = 2 , D = 3, E = 4 };
        [Serializable]
        public enum EventSatsified { Satisfied = 0, Normal = 1, Unsatisfied = 2 };

        [Serializable]
        public class JskeEvent
        {
            #region Attributes

            private int eventID;
            private DateTime eventStart;
            private String eventType;
            private String eventName;
            private int eventDuration;
            private EventPriority eventPriority;
            private EventSatsified eventSatisfy;
            private String notes;
            private Double money;
            
            private int taskID;
            private String taskName;
            private String projectName;
            private String workingHourName;
            private int taskPriority;

            #endregion

            #region Constructors
            public JskeEvent()
            {

            }
            public JskeEvent(DateTime eventStart, String eventName, int eventDuration)
            {
                this.eventStart = eventStart;
                this.eventName = eventName;
                this.eventDuration = eventDuration;
            }
            public JskeEvent(DateTime eventStart, int eventDuration)
            {
                this.eventStart = eventStart;
                this.eventDuration = eventDuration;
            }
            #endregion

            #region Properties

            public int EventID
            {
                get { return this.eventID; }
                set { this.eventID = value; }
            }

            public DateTime EventStart
            {
                get { return this.eventStart; }
                set { this.eventStart = value; }
            }

            public String EventType
            {
                get { return this.eventType; }
                set { this.eventType = value; }
            }

            public String EventName
            {
                get { return this.eventName; }
                set { this.eventName = value; }
            }

            public int EventDuration
            {
                get { return this.eventDuration; }
                set { this.eventDuration = value; }
            }

            public EventPriority EventPriority
            {
                get { return this.eventPriority; }
                set { this.eventPriority = value; }
            }

            public int TaskID
            {
                get { return this.taskID; }
                set { this.taskID = value; }
            }

            public String TaskName
            {
                get { return this.taskName; }
                set { this.taskName = value; }
            }

            public String ProjectName
            {
                get { return this.projectName; }
                set { this.projectName = value; }
            }

            public String WorkingHourName
            {
                get { return this.workingHourName; }
                set { this.workingHourName = value; }
            }

            public int TaskPriority
            {
                get { return this.taskPriority; }
                set { this.taskPriority = value; }
            }

            public EventSatsified EventSatisfy
            {
                get { return this.eventSatisfy; }
                set { this.eventSatisfy = value; }
            }

            public String Notes 
            { 
                get { return this.notes; } 
                set { this.notes = value; } 
            }

            public Double Money
            {
                get { return this.money; }
                set { this.money = value; }
            }

            #endregion
        }

        [Serializable]
        public class EventType
        {
            #region Attributes

            List<String> typeName = new List<String>();

            #endregion

            #region Constructors

            public EventType()
            {
                //typeName.Add("Email");
                //typeName.Add("Wait");
                //typeName.Add("Break");
                //typeName.Add("Eat");
                //typeName.Add("Bath");
                //typeName.Add("Sleep");
                //typeName.Add("Meeting");
                //typeName.Add("Telephone");
                //typeName.Add("Internet");
                //typeName.Add("Move");
                //typeName.Add("Paper & Document");
                //typeName.Add("Prepare");
                //typeName.Add("Planning");
                //typeName.Add("Leave");
                //typeName.Add("Gossip");
                //typeName.Add("Others");
            }

            #endregion

            #region Properties

            public List<String> TypeName
            {
                get { return this.typeName; }
                set { this.typeName = value; }
            }

            #endregion

            #region Method

            public void Add(string evt)
            {
                if (typeName.Contains(evt) == false)
                    typeName.Add(evt);
            }
            public void Delete(string evt)
            {
                typeName.Remove(evt);
            }

            #endregion
        }

        [Serializable]
        public class TaskDetailAnalysis
        {
            #region Attributes

            private int taskID;
            private String taskName;
            private Double speed;
            private DateTime predictingTime;
            private String analysisRept;

            #endregion

            #region Properties

            public int TaskID
            {
                get { return this.taskID; }
                set { this.taskID = value; }
            }

            public String TaskName
            {
                get { return this.taskName; }
                set { this.taskName = value; }
            }

            public Double Speed
            {
                get { return this.speed; }
                set { this.speed = value; }
            }

            public DateTime PredictingTime
            {
                get { return this.predictingTime; }
                set { this.predictingTime = value; }
            }

            public String AnalysisRept
            {
                get { return this.analysisRept; }
                set { this.analysisRept = value; }
            }



            #endregion
        }

        [Serializable]
        public class AnalysisDS
        {
            #region Attributes

            private String content;
            private List<TaskDetailAnalysis> listTaskDetailAnalysis = new List<TaskDetailAnalysis>();
            private StatisticDS statisticPriority = new StatisticDS();
            private StatisticDS statisticEventType = new StatisticDS();
            private StatisticDS statisticEventSatisfy = new StatisticDS();
            private String eventPriorityConclusion;
            private String eventTypeConclusion;
            private String eventSatisfyConclusion;
            #endregion

            #region Properties

            public String Content
            {
                get { return this.content; }
                set { this.content = value; }
            }

            public List<TaskDetailAnalysis> ListTaskDetailAnalysis
            {
                get { return this.listTaskDetailAnalysis; }
                set { this.listTaskDetailAnalysis = value; }
            }

            public StatisticDS StatisticPriority
            {
                get { return this.statisticPriority; }
                set { this.statisticPriority = value; }
            }

            public StatisticDS StatisticEventType
            {
                get { return this.statisticEventType; }
                set { this.statisticEventType = value; }
            }

            public StatisticDS StatisticEventSatisfy
            {
                get { return this.statisticEventSatisfy; }
                set { this.statisticEventSatisfy = value; }
            }

            public String EventPriorityConclusion
            {
                get { return this.eventPriorityConclusion; }
                set { this.eventPriorityConclusion = value; }
            }

            public String EventTypeConclusion
            {
                get { return this.eventTypeConclusion; }
                set { this.eventTypeConclusion = value; }
            }

            public String EventSatisfyConclusion
            {
                get { return this.eventSatisfyConclusion; }
                set { this.eventSatisfyConclusion = value; }
            }

            #endregion
        }

        [Serializable]
        public class StatisticItem
        {
            public String Name{get; set;}
            public Double Number{get; set;}
            public StatisticItem(String s, Double d)
            {
                this.Name = s;
                this.Number = d;
            }
        }
        [Serializable]
        public class StatisticDS
        {
            #region Attributes
            //private List<String> name = new List<String>();
            //private List<Double> number = new List<Double>();
            private List<StatisticItem> listStatisticData = new List<StatisticItem>();
            #endregion

            #region Properties
            //public List<String> Name
            //{
            //    get { return this.name; }
            //    set { this.name = value; }
            //}

            //public List<Double> Number
            //{
            //    get { return this.number; }
            //    set { this.number = value; }
            //}

            public List<StatisticItem> ListStatisticData
            {
                get { return this.listStatisticData; }
                set { this.listStatisticData = value; }
            }
            #endregion

            #region Method

            //public int count()
            //{
            //    return this.name.Count();
            //}

            public void add(String name, Double number)
            {
                this.listStatisticData.Add(new StatisticItem(name, number));
            }

            //public void insert(int index, String name, Double number)
            //{
            //    this.name.Insert(index, name);
            //    this.number.Insert(index, number);
            //}

            //public void insertFirst(String name, Double number)
            //{
            //    insert(0, name, number);
            //}

            //public void remove(String name)
            //{
            //    this.number.RemoveAt(this.name.IndexOf(name));
            //    this.name.Remove(name);
            //}

            //public void removeAt(int index)
            //{
            //    this.name.RemoveAt(index);
            //    this.number.RemoveAt(index);
            //}

            //public void removeRange(int index, int count)
            //{
            //    this.name.RemoveRange(index, count);
            //    this.number.RemoveRange(index, count);
            //}

            //public void clear()
            //{
            //    this.name.Clear();
            //    this.number.Clear();
            //}

            #endregion
        }
    }

    [Serializable]
    public class DiaryDS
    {
        #region Attributes
        private List<JskeEvent> listEventInDiary = new List<JskeEvent>();
        private EventType theEventType = new EventType();
        private List<FreeTimeBlock> listFTLAfterSched = new List<FreeTimeBlock>();
        private AnalysisDS analysis = new AnalysisDS();

        #endregion

        #region Properties
        public List<JskeEvent> ListEventInDiary
        {
            get { return this.listEventInDiary; }
            set { this.listEventInDiary = value; }
        }
        public EventType TheEventType
        {
            get { return this.theEventType; }
            set { this.theEventType = value; }
        }

        public List<FreeTimeBlock> ListFTLAfterSched
        {
            get { return this.listFTLAfterSched; }
            set { this.listFTLAfterSched = value; }
        }

        public AnalysisDS Analysis
        {
            get { return this.analysis; }
            set { this.analysis = value; }
        }

        #endregion

        #region Constructor

        #endregion

        #region Methods

        public void loadEvents(ref List<JskeEvent> eventFromDiary, 
            ref List<JskeEvent> eventFromSchedule, 
            List<JskeEvent> listScheduledEvent,
            DateTime FromDate, DateTime ToDate)
        {
            foreach (JskeEvent tempEvt in listEventInDiary)
            {
                if (tempEvt.EventStart.Date < FromDate || tempEvt.EventStart.Date > ToDate)
                {
                    continue;
                }
                eventFromDiary.Add(tempEvt);
            }
            foreach (JskeEvent tempEvt in listScheduledEvent)
            {
                if (tempEvt.EventStart.Date < FromDate || tempEvt.EventStart.Date > ToDate)
                {
                    continue;
                }
                eventFromSchedule.Add(tempEvt);
            }
        }

        public void updateEvent(ref List<JskeEvent> eventFromSchedule, ref List<JskeEvent> listScheduledEvent)
        {
            foreach (JskeEvent tempEvt in eventFromSchedule)
            {
                listScheduledEvent.Remove(tempEvt);
                listEventInDiary.Add(tempEvt);
            }
            listEventInDiary.Sort(delegate(JskeEvent evt1, JskeEvent evt2)
            {
                return evt1.EventStart.CompareTo(evt2.EventStart);
            });
        }

        public void analyze(DateTime FromDate, DateTime ToDate)
        {
            List<JskeEvent> eventForAnalyzing = new List<JskeEvent>();
            Double TotalTime = 0;
            foreach (JskeEvent tempEvt in listEventInDiary)
            {
                if (tempEvt.EventStart.Date < FromDate || tempEvt.EventStart.Date > ToDate)
                {
                    continue;
                }

                eventForAnalyzing.Add(tempEvt);

                TotalTime += tempEvt.EventDuration;
            }

            analyze(eventForAnalyzing, TotalTime);
        }

        public void analyze(List<JskeEvent> eventForAnalyzing, Double TotalTime)
        {
            List<JskeEvent> tempEvtList = new List<JskeEvent>();

            #region thống kê cho EventPriority
            eventForAnalyzing.Sort(delegate(JskeEvent evt1, JskeEvent evt2)
            {
                return evt1.EventPriority.CompareTo(evt2.EventPriority);
            });

            foreach (JskeEvent tempEvt in eventForAnalyzing)
            {
                analysis.StatisticPriority.add(tempEvt.EventPriority.ToString(), tempEvt.EventDuration);
            }

            for (int i = 0; i < analysis.StatisticPriority.ListStatisticData.Count - 1; i++)
            {
                if (analysis.StatisticPriority.ListStatisticData[i].Name == analysis.StatisticPriority.ListStatisticData[i + 1].Name)
                {
                    analysis.StatisticPriority.ListStatisticData[i].Number += analysis.StatisticPriority.ListStatisticData[i + 1].Number;
                    analysis.StatisticPriority.ListStatisticData.RemoveAt(i + 1);
                    i--;
                }
            }

            for (int i = 0; i < analysis.StatisticPriority.ListStatisticData.Count; i++)
            {
                //Xoa nhung Event nao khong co Priority statistics (<=0)
                if (analysis.StatisticPriority.ListStatisticData[i].Number <= 0)
                {
                    //analysis.StatisticPriority.Name.Remove(analysis.StatisticPriority.Name[i]);
                    //analysis.StatisticPriority.Number.Remove(analysis.StatisticPriority.Number[i]);
                    analysis.StatisticPriority.ListStatisticData.Remove(analysis.StatisticPriority.ListStatisticData[i]);
                    i--;
                }
                else
                {
                    //analysis.StatisticPriority.ListStatisticData[i].Number = 100 * analysis.StatisticPriority.ListStatisticData[i].Number / TotalTime;
                }
            }
            #endregion

            #region góp ý cho EventPriority
            tempEvtList.Clear();
            foreach (JskeEvent tempEvt in eventForAnalyzing)
            {
                if (tempEvt.EventPriority == EventPriority.E)
                {
                    tempEvtList.Add(tempEvt);
                }
            }

            tempEvtList.Sort(delegate(JskeEvent evt1, JskeEvent evt2)
            {
                return evt2.EventSatisfy.CompareTo(evt1.EventSatisfy);
            });
            if (tempEvtList.Count > 0)
            {
                analysis.EventPriorityConclusion = "Chúng tôi cho rằng những việc dưới đây đang lãng phí thời gian của bạn.\r\n"+
                    " Bạn nên loại chúng ra khỏi cuộc sống bằng mọi cách:" +
                    "\r\n";
                tempEvtList.Sort(delegate(JskeEvent e1, JskeEvent e2)
                {
                    return e1.EventType.CompareTo(e2.EventType);
                });
                foreach (JskeEvent tempEvt in tempEvtList)
                {
                    analysis.EventPriorityConclusion += "\t+[" + tempEvt.EventType + "]" + tempEvt.EventName + "\r\n";
                }
            }
            else
            {
                analysis.EventPriorityConclusion = "Chúc mừng bạn! \r\n\r\n"
                    +"Bạn luôn làm những công việc có giá trị nhất.\r\n "+
                    "Trong giai đoạn này bạn đã quản lý thời gian rất tốt.";
            }
            #endregion

            #region thống kê cho EventType
            eventForAnalyzing.Sort(delegate(JskeEvent evt1, JskeEvent evt2)
            {
                return evt1.EventType.CompareTo(evt2.EventType);
            });

            foreach (JskeEvent tempEvt in eventForAnalyzing)
            {
                analysis.StatisticEventType.add(tempEvt.EventType, tempEvt.EventDuration);
            }

            for (int i = 0; i < analysis.StatisticEventType.ListStatisticData.Count - 1; i++)
            {
                if (analysis.StatisticEventType.ListStatisticData[i].Name == analysis.StatisticEventType.ListStatisticData[i + 1].Name)
                {
                    analysis.StatisticEventType.ListStatisticData[i].Number += analysis.StatisticEventType.ListStatisticData[i + 1].Number;
                    analysis.StatisticEventType.ListStatisticData.RemoveAt(i + 1);
                    i--;
                }
            }

            for (int i = 0; i < analysis.StatisticEventType.ListStatisticData.Count; i++)
            {
                //Bo nhung EventType khong co Event
                if (analysis.StatisticEventType.ListStatisticData[i].Number <= 0)
                {
                    //analysis.StatisticEventType.Number.Remove(analysis.StatisticEventType.Number[i]);
                    //analysis.StatisticEventType.Name.Remove(analysis.StatisticEventType.Name[i]);
                    analysis.StatisticEventType.ListStatisticData.Remove(analysis.StatisticEventType.ListStatisticData[i]);
                    i--;
                }
                else
                {
                    //analysis.StatisticEventType.ListStatisticData[i].Number = 100 * analysis.StatisticEventType.ListStatisticData[i].Number / TotalTime;
                }
            }
            #endregion

            #region Góp ý cho EventType
            analysis.EventTypeConclusion = "Chúng tôi nhận thấy bạn đang ngủ quá ít.\r\n\r\n\r\n" +
"Kết quả phân tích cho thấy, sau 25 năm, những người thường xuyên ngủ ít hơn 6 tiếng vào buổi tối có nguy cơ tử vong lớn hơn 12% so với những người ngủ từ 6 tới 8 tiếng. \r\n\r\n" +
"Nguồn: lấy từ phân tích của giáo sư Francesco Cappuccio - một nhà khoa học thuộc Chương trình Giấc ngủ, Sức khỏe và Xã hội của Đại học Warwick, Anh cùng các đồng nghiệp phân tích dữ liệu của 1,5 triệu người tại Anh, Mỹ, châu Âu và Đông Á.\r\n\r\n"+
"Link: http://vnexpress.net/GL/Khoa-hoc/2010/05/3BA1B90E/";
            #endregion

            #region thống kê cho EventSatisfy
            eventForAnalyzing.Sort(delegate(JskeEvent evt1, JskeEvent evt2)
            {
                return evt1.EventSatisfy.CompareTo(evt2.EventSatisfy);
            });

            foreach (JskeEvent tempEvt in eventForAnalyzing)
            {
                analysis.StatisticEventSatisfy.add(tempEvt.EventSatisfy.ToString(), tempEvt.EventDuration);
            }

            for (int i = 0; i < analysis.StatisticEventSatisfy.ListStatisticData.Count - 1; i++)
            {
                if (analysis.StatisticEventSatisfy.ListStatisticData[i].Name == analysis.StatisticEventSatisfy.ListStatisticData[i + 1].Name)
                {
                    analysis.StatisticEventSatisfy.ListStatisticData[i].Number += analysis.StatisticEventSatisfy.ListStatisticData[i + 1].Number;
                    analysis.StatisticEventSatisfy.ListStatisticData.RemoveAt(i + 1);
                    i--;
                }
            }

            for (int i = 0; i < analysis.StatisticEventSatisfy.ListStatisticData.Count; i++)
            {
                //Xoa nhung Event nao khong co StatisticEventSatisfy statistics (<=0)
                if (analysis.StatisticEventSatisfy.ListStatisticData[i].Number <= 0)
                {
                    //analysis.StatisticPriority.Name.Remove(analysis.StatisticPriority.Name[i]);
                    //analysis.StatisticPriority.Number.Remove(analysis.StatisticPriority.Number[i]);
                    analysis.StatisticEventSatisfy.ListStatisticData.Remove(analysis.StatisticEventSatisfy.ListStatisticData[i]);
                    i--;
                }
                else
                {
                    //analysis.StatisticPriority.ListStatisticData[i].Number = 100 * analysis.StatisticPriority.ListStatisticData[i].Number / TotalTime;
                }
            }
            #endregion

            #region góp ý cho EventSatisfy
            tempEvtList.Clear();
            foreach (JskeEvent tempEvt in eventForAnalyzing)
            {
                if (tempEvt.EventSatisfy == EventSatsified.Unsatisfied)
                {
                    tempEvtList.Add(tempEvt);
                }
            }

            tempEvtList.Sort(delegate(JskeEvent evt1, JskeEvent evt2)
            {
                return evt2.EventPriority.CompareTo(evt1.EventPriority);
            });

            if (tempEvtList.Count > 0)
            {
                analysis.EventSatisfyConclusion = "Chúng tôi nhận thấy có một số công việc dưới đây bạn không thỏa mãn với kết quả của Chúng. \r\n\r\n"
                    +"Có lẽ bạn nên tìm hiểu một số mẹo để cải thiện kết quả cho những công việc này:\r\n";
                tempEvtList.Sort(delegate(JskeEvent e1, JskeEvent e2)
                {
                    return e1.EventType.CompareTo(e2.EventType);
                });
                foreach (JskeEvent tempEvt in tempEvtList)
                {
                    analysis.EventSatisfyConclusion += "\t+["+tempEvt.EventType+"]"+tempEvt.EventName + "\r\n";
                }
            }
            else
            {
                analysis.EventSatisfyConclusion = "Chúc mừng bạn! \r\n\r\n"
                    +"Bạn luôn hài lòng với kết quả công việc và chúng tôi nhận thấy bạn đã làm các công việc có độ quan trọng cao. \r\n"
                    +"Trong giai đoạn này bạn đã quản lý thời gian rất tốt.";
            }
            #endregion
        }

        public List<JskeEvent> loadEventInDiary(DateTime from, DateTime to)
        {
            List<JskeEvent> result = new List<JskeEvent>();

            for (int i = 0; i < listEventInDiary.Count; i++)
            {
                if (listEventInDiary[i].EventStart.Date >= from || listEventInDiary[i].EventStart.Date <= to)
                {
                    result.Add(listEventInDiary[i]);
                }
            }

            return result;
        }

        #endregion

        
    }
}
